import axios, { type Method } from 'axios'
import { useUserStore } from '@/stores'
import { showToast } from 'vant'
import router from '@/router'

// 去以前我们在 人资、小程序、黑马面面、黑马头条 等项目里面的 代码配置，直接拿过来用，完成 从 0 - 1的request搭建
const instance = axios.create({
  // TODO 1. 基础地址，超时时间
  baseURL: 'https://consult-api.itheima.net',
  // timeout请求超时时间，超过了6s就会报错
  timeout: 6000
})

instance.interceptors.request.use(
  (config) => {
    // TODO 2. 携带token
    const store = useUserStore()
    if (store.user?.token) {
      config.headers.authorization = `Bearer ${store.user.token}`
    }
    return config
  },
  (err) => Promise.reject(err)
)

instance.interceptors.response.use(
  (res) => {
    // TODO 3. 处理业务失败
    // TODO 4. 摘取核心响应数据
    // 下面这句话是人资项目里面  以前导出excel 服务器返回的二进制数据的单独处理
    // if (response.data instanceof Blob) return response.data

    // 先把失败的请求处理了，return以后， 后面的代码都是成功的代码
    if (res.data?.code !== 10000) {
      // 这个if分支，表示业务成功 --- 例如登录， 账号密码错误了，但是http请求是成功
      showToast(res.data?.message || '业务失败')
      return Promise.reject(res)
    }
    // 这里是请求一定成功执行的逻辑片段
    return res.data
  },
  (err) => {
    // TODO 5. 处理401错误
    if (err?.response?.status === 401) {
      const store = useUserStore()
      store.delUser()

      router.push('/login')
    }

    return Promise.reject(err)
  }
)

type Data<T> = {
  code: number
  message: string
  data: T
}

// 封装一个自己的request函数，方便外面调用，不需要写api文件夹
// 4. 请求工具函数
// 这里是函数request调用的地方，接受一个泛型
export const request = <T>(url: string, method: Method = 'GET', submitData?: object) => {
  // 指定axios返回值的类型，是他默认返回类型的 详细版本，
  return instance.request<T, Data<T>>({
    url,
    method,
    [method.toUpperCase() === 'GET' ? 'params' : 'data']: submitData
  })
}

export default instance
